#! /usr/bin/ruby

require 'fileutils'
require './lib/maruku.rb'
require 'date'

def growl(message)
  unless File.exist?("/usr/local/bin/growlnotify")
    puts "growlnotify is not installed in /usr/local/bin/; you can install it from the Growl DMG."
    puts "message: #{message}"
    return
  end
    
  %x(/usr/local/bin/growlnotify --name Build --message '#{message}')
end

def load_release_notes
  changelog = File.open("../onepasswd_ext/CHANGELOG").readlines rescue nil
  return if changelog.nil?
  
  result = ["# Release Notes\n"]
  
  skip = false
  for l in changelog do
    if l =~ /\[(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d): (\S+) (\d+)\]/
      date = DateTime.strptime($1, "%Y-%m-%d %H:%M")
      version = $2
      build = $3
      
      result << "## #{date.strftime('%B %d, %Y')} -- 1Password #{version} <small>(build #{build})</small>\n"
    elsif l =~ /\[(\d\d\d\d-\d\d-\d\d): (\S+) (\d+)\]/
      date = DateTime.strptime($1, "%Y-%m-%d")
      version = $2
      build = $3
      
      result << "## #{date.strftime('%B %d, %Y')} -- 1Password #{version} <small>(build #{build})</small>\n"
    elsif l =~ /\[DESCRIPTION\]/
      skip = true
    elsif l =~ /\[\/DESCRIPTION\]/
      skip = false
    else
      result << l.gsub(/\[NEW\]/, "* **NEW**").gsub(/\[CHANGED\]/, "* **CHANGED**").gsub(/\[FIXED\]/, "* **FIXED**") unless skip
    end
  end
  
  return result
end

def scan_section(section_name, section_folder)
  doc_files = Dir[section_folder+'/*']
  doc_files.sort!
  docs = []

  overview_contents = File.open("#{section_folder}/#{section_name}.markdown").read rescue "## #{section_name}\n\nThere was no overview file."
  overview_title = $1 if overview_contents =~ %r{# (.*)}
  
  for doc_file in doc_files do
    name = nil
    name = $1 if doc_file =~ /^source\/#{@platform}\/.+\/\d\d\d[ _-](.+)\.markdown$/
    next unless name
    
    if name == "release_notes"
      content = load_release_notes
    else
      content = File.open(doc_file).readlines
    end
    
    if content.nil?
      puts "Warning: content nil for `#{doc_file}`"
      next 
    end
    
    title = content[0].strip rescue name
    title = $1 if title =~ /#\s+(.*)/
    
    docs << { :name => name, :title => title, :content => content * "" }
  end

  return {
    :name => section_name,
    :title => overview_title,
    :overview => overview_contents,
    :docs => docs
  }
end

def load_sections
  folders = Dir["source/#{@platform}/*"]
  folders.sort!

  sections = []
  for folder in folders do
    next if folder =~ /^source\/#{@platform}\/(images|extra)$/
    name = $1 if folder =~ /^source\/#{@platform}\/\d\d\d[ _-](.*)$/
  	sections << scan_section(name, folder)
  end

  return sections
end

def format_toc(sections, selected_item)
  toc = ""
  sections.each { |section| 
    html_class = selected_item == section[:name] ? " class='selected'" : ""
    toc += "<h2#{html_class}><a href='#{section[:name]}.html'>#{section[:title]}</a></h2>\n<ol>"
    
    # Temporary hack to keep children off main TOC; should be configured in overview page
    
    if @platform == "Mac"
      next if section[:name] =~ /(knowledgebase|faqs|3_minute_expert|tutorials)/
    end
    
    section[:docs].each { 
      |doc| 
      # Temporary hack to skip WIP articles; should be configured in page
      next if doc[:name] =~ /\_wip$/
      
      html_class = selected_item == doc[:name] ? " class='selected'" : ""
      toc += "<li#{html_class}><a href='#{doc[:name]}.html'>#{doc[:title]}</a></li>" 
    }
    toc += "</ol>"
  }
  
  return toc
end

def prepare_output_folders
  FileUtils.rm_rf("./html/#{@platform}")
  FileUtils.mkdir_p("html/#{@platform}/images") unless File.exists?("html/#{@platform}/images")
  FileUtils.mkdir_p("html/#{@platform}/no_toc") unless File.exists?("html/#{@platform}/no_toc")
  FileUtils.cp("template/#{@platform}/#{@template_name}/style.css", "html/#{@platform}") 
  FileUtils.cp_r("source/#{@platform}/images", "html/#{@platform}/")
end

def write_content_to_file(filename, title, content)
  document_html = File.open("template/#{@platform}/#{@template_name}/document.html").read
  maruku = Maruku.new(content)
  s = document_html.gsub("[TITLE]", title).gsub("[CONTENT]", maruku.to_html)
  s.gsub!("[TOC]", format_toc(@sections, filename))
  
  folder = $1 if filename =~ /(.*?)\//
  FileUtils.mkdir("html/#{@platform}/#{folder}") unless folder.nil? || File.exists?("html/#{@platform}/#{folder}")
  
  File.open("html/#{@platform}/#{filename}.html", "w").write(s)
end

def write_html_docs(sections)
  for section in sections do 
    write_content_to_file(section[:name], section[:title], section[:overview])
    for doc in section[:docs] do
      write_content_to_file(doc[:name], doc[:title], doc[:content])
    end
  end
end

def process_extra_docs
  for doc in Dir["source/#{@platform}/extra/*"]
    name = $1 if doc =~ /source\/#{@platform}\/extra\/(.*)\.markdown/
    content = File.open(doc).read
    write_content_to_file(name, "1Password User Guide", content)
  end
end

def run(platform)
  growl "Started generating html help... "
  @platform = platform
  @sections = load_sections

  @template_name = "standard"
  prepare_output_folders
  
#  write_toc(sections)
  write_html_docs(@sections)
  process_extra_docs
  
  `cd ./html/Mac; /Developer/Applications/Utilities/Help\\ Indexer.app/Contents/MacOS/Help\\ Indexer  . -GenerateSummaries YES -PantherIndexing NO -TigerIndexing YES -LeopardIndexing YES`
  
  growl "Finished generating html help."
end

run("Mac")
run("iPhone")

# Designate root page as index.
puts `cp ./html/Mac/1password_help.html ./html/Mac/index.html`
puts `cp ./html/iPhone/iphone_guide.html ./html/iPhone/index.html`

# Cleanup .svn right away to prevent accidental packaging 
puts "Removing .svn folders and .DS_Store files"
puts `find ./html -type d -name .svn | xargs rm -rf`
puts `find ./html -type f -name .DS_Store | xargs rm -rf`


